
; ===============================================================
; Aug 2015
; ===============================================================
; 
; uint16_t in_key_scancode(int c)
;
; Return a 16-bit scancode corresponding to char c.  The scancode
; encodes information on how to quickly detect if the key
; corresponding to char c is pressed on the keyboard.
;
; ===============================================================

SECTION code_clib
SECTION code_input

PUBLIC asm_in_key_scancode

EXTERN in_key_translation_table, error_einval_zc

asm_in_key_scancode:

   ; enter :  l = char c
   ;
   ; exit  : success
   ;
   ;            hl = scancode
   ;                 l = bits 765: alt,ctrl,shift ; bits 3210: key row
   ;                 h = 8-bit mask
   ;            carry reset
   ;
   ;         fail if char cannot be generated by keypress
   ;
   ;            hl = 0
   ;            carry set, errno = EINVAL
   ;
   ; uses   : af, bc, de, hl
   
   ld a,l                      ; a = char c
   
   ld hl,in_key_translation_table
   ld bc,320
   
   cpir                        ; find char in table
   jp nz, error_einval_zc      ; if not found

   ld hl,319
   
   xor a
   ld e,a
   
   sbc hl,bc                   ; hl = key_index of ascii code 0..319
   ld a,l
   
alt:

   dec h
   jr z, alt_pressed

   cp 240
   jr c, ctrl

alt_pressed:

   set 7,e
   sub 240
   
   jr key_row

ctrl:

   cp 160
   jr c, shift
   
   set 6,e
   sub 160
   
   jr key_row

shift:

   cp 80
   jr c, key_row
   
   set 5,e
   sub 80

key_row:

   ; a = sub-table offset 0-79
   ; e = bits 765: alt,ctrl,shift
   
   ld h,a
   
   srl a
   srl a
   srl a
   or e
   ld l,a                      ; l = bits 765: alt,ctrl,shift ; bits 3210: key row
   
key_mask:

   ld a,h
   and $07                     ; a = bit position of key 0-7

   inc a
   ld b,a
   ld a,$80

mask_loop:

   rlca
   djnz mask_loop
   
   ld h,a                      ; h = 8-bit mask
   
   or a
   ret
